<?php

namespace App\Repositories\Bonus;

use App\Criteria\Bonus\GetCanUseByUserCriteria;
use Illuminate\Support\Facades\DB;
use Prettus\Repository\Eloquent\BaseRepository;
use Prettus\Repository\Criteria\RequestCriteria;
use App\Repositories\Bonus\UserBonusRepository;
use App\Models\Bonus\UserBonus;
use App\Validators\Bonus\UserBonusValidator;

/**
 * Class UserBonusRepositoryEloquent
 * @package namespace App\Repositories\Bonus;
 */
class UserBonusRepositoryEloquent extends BaseRepository implements UserBonusRepository
{
    /**
     * @var array
     */
    protected $fields = [
        't.type_id',
        't.type_name',
        't.type_money',
        't.is_limit_buy',
        'b.bonus_id',
        't.shopping_type',
        't.shopping_type_info',
        't.use_start_date',
        't.use_end_date',
        't.min_goods_amount',
        't.has_effective_days',
        't.effective_days',
        't.include_promotion',
        't.is_limit_landmark',
        't.act_landmark_ext',
        't.bonus_discount_type',
        't.place_order_start_date',
        't.place_order_end_date',
        't.shipping_start_date',
        't.shipping_end_date',
        'b.get_time',
        'b.deadline',
        'if(b.used_time>0,1,0) as is_use',
        'if(b.deadline>0,b.deadline,t.use_end_date) as can_use_time',
    ];

    /**
     * Specify Model class name
     *
     * @return string
     */
    public function model()
    {
        return UserBonus::class;
    }

    /**
    * Specify Validator class name
    *
    * @return mixed
    */
    public function validator()
    {

        return UserBonusValidator::class;
    }


    /**
     * Boot up the repository, pushing criteria
     */
    public function boot()
    {
        $this->pushCriteria(app(RequestCriteria::class));
    }

    /**
     * @author yangzhic
     * @param int $userId
     * @param int $date
     * @return array
     */
    public function getCanUseBonus(int $userId,int $date=0){
        $sql = "SELECT t.type_id, t.type_name, t.type_money, t.is_limit_buy,b.bonus_id,t.shopping_type,t.shopping_type_info,t.use_start_date,t.use_end_date,t.min_goods_amount,t.has_effective_days,t.effective_days,t.include_promotion,t.is_limit_landmark,t.act_landmark_ext,t.bonus_discount_type,t.place_order_start_date,t.place_order_end_date,t.shipping_start_date,t.shipping_end_date,b.get_time,b.deadline,if(b.used_time>0,1,0) as is_use,if(b.deadline>0 and b.deadline< ?,1,if(b.deadline=0 and t.use_end_date<?,1,0)) as is_time_out,if(b.deadline>0,b.deadline,t.use_end_date) as can_use_time " .
            "FROM " . DB::getTablePrefix(). "bonus_type AS t," .
            DB::getTablePrefix()  . "user_bonus AS b " .
            "WHERE t.type_id = b.bonus_type_id " .
            "AND (if(b.deadline>0 and b.deadline< ?,1,if(b.deadline=0 and t.use_end_date< ?,1,0))) = 0 ".
            "AND b.used_time = 0 ".
            "AND b.user_id = ? " .
            "AND b.order_id = 0 ".
            "AND t.bonus_type = 0 "; //只获取订单金额抵扣红包

        if(empty($date)){
            $today = gm_time();
        }else{
            $today = $date;
        }

        $bonus_list = DB::select($sql,[$today,$today,$today,$today,$userId]);

        return $bonus_list;
    }

    /**
     * 获取用户红包
     * @author yangzhic
     * @param int $userId
     * @param int $show_all
     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
     */
    public function getUserBonusByUserId(int $userId, int $show_all){
        $field = [
            'ub.bonus_id',
            'ub.bonus_type_id',
            'ub.bonus_sn',
            'ub.user_id',
            'ub.used_time',
            'ub.order_id',
            'ub.emailed',
            'ub.deadline',
            'bt.*'
        ];

        $current_time = gm_time();
        $bonus_model = DB::table('user_bonus as ub')->leftJoin('bonus_type as bt','ub.bonus_type_id','=','bt.type_id');
        if($show_all==2){   //只显示未过期的红包
            $bonus_model = $bonus_model->whereRaw("((".DB::getTablePrefix()."ub.deadline>0 and ".DB::getTablePrefix()."ub.deadline>=?) or (".DB::getTablePrefix()."ub.deadline=0 and ".DB::getTablePrefix()."bt.use_end_date>=?))",[$current_time,$current_time]);
        }elseif($show_all==3){  //只显示过期红包
            $bonus_model = $bonus_model->whereRaw("((".DB::getTablePrefix()."ub.deadline>0 and ".DB::getTablePrefix()."ub.deadline<?) or (".DB::getTablePrefix()."ub.deadline=0 and ".DB::getTablePrefix()."bt.use_end_date<?))",[$current_time,$current_time]);
        }

        $data = $bonus_model->select($field)
            ->addSelect(
                DB::raw('if('.DB::getTablePrefix().'ub.used_time>0,1,0) as is_use')
            )
            ->addSelect(
                DB::raw('if('.DB::getTablePrefix().'ub.deadline>0 and '.DB::getTablePrefix().'ub.deadline<'.$current_time.',1,if('.DB::getTablePrefix().'ub.deadline=0 and '.DB::getTablePrefix().'bt.use_end_date<'.$current_time.',1,0)) as is_time_out')
            )
            ->where('ub.user_id','=',$userId)
            ->paginate();
        return $data;
    }

    /**
     * @author yangzhic
     * @param $bonusTypeId
     * @return array
     */
    public function getBonusConfigByTypeId($bonusTypeId){
        $fields = [
            'bcf.*',
            'g.goods_name',
            'c.cat_name',
            'b.brand_name'
        ];
        return DB::table('bonus_config as bcf')
                    ->leftJoin('goods as g','bcf.goods_id','=','g.goods_id')
                    ->leftJoin('category as c','bcf.cate_id','=','c.cat_id')
                    ->leftJoin('brand as b','bcf.brand_id','=','b.brand_id')
                    ->where('bcf.bonus_type_id','=',$bonusTypeId)
                    ->where('bcf.status','=',1)
                    ->select($fields)
                    ->get()
                    ->toArray();
    }

    /**
     * @author yangzhic
     * @param int $bonusId
     * @param array $param
     * @return mixed
     * @throws \Prettus\Repository\Exceptions\RepositoryException
     */
    public function useBonus(int $bonusId,array $param){
        return $this->where('bonus_id',$bonusId)->update($param);
    }
}
